home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 August: Tool Chest / Apple_Developer_Group_August_1996_Tool_Chest.iso / Sample Code / QuickTime / ChromaKeyMovie / Sources / moviecontrol.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-20  |  12.1 KB  |  440 lines  |  [TEXT/MPS ]

  1. /****************************************************/
  2. /*                                                     */
  3. /*    File:        moviecontrol.c                         */
  4. /*                                                      */
  5. /*    Program:    ChromaKeyMovie                        */
  6. /*                                                     */
  7. /*    By:            Jason Hodges-Harris                    */
  8. /*                                                    */
  9. /*    Copyright:    © 1995 by Apple Computer, Inc.,        */ 
  10. /*                    all rights reserved.            */        
  11. /*                                                    */
  12. /****************************************************/
  13.  
  14.  
  15. #ifndef __COLORPICKER__
  16. #include <ColorPicker.h>
  17. #endif
  18.  
  19. #ifndef __MOVIES__
  20. #include <Movies.h>
  21. #endif
  22.  
  23. #ifndef __QDOFFSCREEN__
  24. #include <QDOffscreen.h>
  25. #endif
  26.  
  27. #ifndef __RESOURCES__
  28. #include <Resources.h>
  29. #endif
  30.  
  31. #ifndef __TOOLUTILS__
  32. #include <ToolUtils.h>
  33. #endif
  34.  
  35. #ifndef __TYPES__
  36. #include <Types.h>
  37. #endif
  38.  
  39.  
  40. // Program headers
  41.  
  42. #ifndef __CHROMAPPHEADER__
  43. #include "ChromaKeyMovie.app.h"
  44. #endif
  45.  
  46. #ifndef __CHROMAPROTOSHEADER__
  47. #include "ChromaKeyMovie.protos.h"
  48. #endif
  49.  
  50.  
  51. //    Global Variables
  52.  
  53.  
  54. /* Global GWorld storage for the QuickTime movie.
  55.    If multiple windows are to be implemented, then these
  56.    declarations should be moved into the window document
  57.    structure, as each movie requires 3 offscreen ports*/
  58.  
  59. GWorldPtr            gOffscreenPort,
  60.                     gBackGroundPort,
  61.                     gBackGroundPicture;
  62. PixMapHandle        gMoviePixmap,
  63.                     gBackGndPixmap,
  64.                     gBackGndPictPM;
  65.  
  66. extern RGBColor        kRGBWhite,
  67.                     kRGBBlack,
  68.                     gKeyColor;
  69.  
  70. extern Boolean        gMovieBackGrnd;
  71. extern Boolean        gDone;
  72. extern Boolean        gMovieOpen;
  73.  
  74.  
  75. /* The PlayMovieChroma() function, is called by Open menu item and
  76.    initialises the movie's offscreen environments and window port  */
  77.  
  78. #pragma segment Test
  79. Boolean    PlayMovieChroma(void)
  80. {
  81.     PicHandle            thePict;
  82.     GDHandle            oldGDev;
  83.     CWindowPtr            oldPort,
  84.                         theWindow;
  85.     MovieDocHndl        theDocHndl;
  86.     OSErr                theError;
  87.     QDErr                error;
  88.     Rect                theRect;
  89.     Fixed                theData = 0xEFFF;
  90.  
  91.     GetGWorld(&oldPort,&oldGDev);
  92.     thePict = GetPicture(rBackGroundPict);                // load the background picture
  93.     theWindow = OpenCWindow();
  94.     theDocHndl=(MovieDocHndl)GetWRefCon((WindowPtr)theWindow);
  95.     HLock((Handle)theDocHndl);
  96.     theError = LoadOneMovie(theDocHndl);                // load a QuickTime movie
  97.     // Check if the QuickTime movie was successfully loaded.
  98.     if (theError)
  99.     {
  100.         if (theError == kappDefErr)
  101.             DisplayAlert (rGenAlert,rErrMessages,1);
  102.         // return gracefully as cancel button selected or load error occurred
  103.         DisposeHandle((Handle)theDocHndl);
  104.         DisposeWindow((WindowPtr)theWindow);
  105.         return false;
  106.     }
  107.     // get movie frame dimensions
  108.     GetMovieBox((**theDocHndl).theMovie,&theRect);
  109.  
  110.     /* create the offscreen GWorlds to store the background image,
  111.        the current movie frame and the composite image for transferring to the screen */
  112.     
  113.     error = NewGWorld(&gOffscreenPort,0,&theRect,nil,nil,0);
  114.     error |= NewGWorld(&gBackGroundPort,0,&theRect,nil,nil,0);
  115.     error |= NewGWorld(&gBackGroundPicture,1,&(**thePict).picFrame,nil,nil,0);
  116.     // Check if the GWorlds created successfully.
  117.     
  118.     if (error != noErr)
  119.     {
  120.         /* failed to allocate GWorlds, Alert user of 
  121.         problem and exit application as can't continue. */
  122.         DisplayAlert (rGenAlert,rErrMessages,2);
  123.         gDone = true;
  124.         return false;
  125.     }
  126.     /* Get the GWorld PixMaps and lock down the offscreen ports. */
  127.     gMoviePixmap = GetGWorldPixMap(gOffscreenPort);
  128.     gBackGndPixmap = GetGWorldPixMap(gBackGroundPort);
  129.     gBackGndPictPM = GetGWorldPixMap(gBackGroundPicture);
  130.     LockPixels(gMoviePixmap);
  131.     LockPixels(gBackGndPixmap);
  132.     LockPixels(gBackGndPictPM);
  133.     SetGWorld(gBackGroundPicture,nil);
  134.     /* Draw PICT resource into its GWorld. This saves time having
  135.        to reload and draw the PICT for each frame. */
  136.     HLock((Handle)thePict);
  137.     DrawPicture(thePict,&(*gBackGroundPicture).portRect);
  138.     HUnlock((Handle)thePict);
  139.     ReleaseResource((Handle)thePict);
  140.     SetGWorld(oldPort,oldGDev);
  141.     /* Create a movie controller for the movie, get the controller
  142.        dimensions  and its port to that of the visible window */
  143.     (**theDocHndl).theController = 
  144.         NewMovieController((**theDocHndl).theMovie,&theRect,mcTopLeftMovie);
  145.     theError = MCGetControllerBoundsRect((**theDocHndl).theController,&theRect);
  146.     theError = MCSetControllerPort((**theDocHndl).theController,(CGrafPtr)theWindow);
  147.     SetMovieGWorld((**theDocHndl).theMovie,gOffscreenPort,nil);
  148.     SizeWindow((WindowPtr)theWindow,theRect.right,theRect.bottom,true);
  149.     SetWTitle((WindowPtr)theWindow,(**theDocHndl).theFileSpec.name);
  150.     ShowWindow((WindowPtr)theWindow);
  151.     gMovieOpen = true;
  152.     HUnlock((Handle)theDocHndl);
  153.     return true;
  154. }
  155.  
  156.  
  157. /* Simple function to load a QuickTime movie and 
  158.    place the reference into the movie window document*/
  159.  
  160. #pragma segment Test
  161. OSErr    LoadOneMovie(MovieDocHndl theDocH)
  162. {
  163.     StandardFileReply    theMovieFile;
  164.     SFTypeList            myTypes = {MovieFileType};
  165.     OSErr                error;
  166.     short                myMovieResFile;
  167.     Boolean                movieChanged;
  168.     
  169.     StandardGetFilePreview(nil,1,myTypes,&theMovieFile);
  170.     if (theMovieFile.sfGood)
  171.     {
  172.         error = OpenMovieFile(&theMovieFile.sfFile,&myMovieResFile,fsRdPerm);
  173.         if (error == noErr)
  174.         {
  175.             (**theDocH).theMovieResID = 0;    // get first movie
  176.             error = NewMovieFromFile(&(**theDocH).theMovie,myMovieResFile,&(**theDocH).theMovieResID,
  177.                             nil,newMovieActive,&movieChanged);
  178.             if(error == noErr)
  179.             {
  180.                 (**theDocH).theFileSpec = theMovieFile.sfFile;
  181.                 CloseMovieFile (myMovieResFile);
  182.                 return noErr;
  183.             }
  184.         }
  185.         return kappDefErr;    // error loading movie
  186.     }
  187.     return -kappDefErr;    // cancel selected
  188. }
  189.  
  190.  
  191. /* When the TransparentColor() function is called,
  192.    it displays the Color Picker and sets the key
  193.    color to the value returned by the Picker */
  194.  
  195. #pragma segment Test
  196. void    TransparentColor()
  197. {
  198.     RGBColor        theNewColor;
  199.     Point            thePoint = {0,0};
  200.     
  201.     // alter the key color if OK selected
  202.     if (GetColor(thePoint,"\pSelect Color",&gKeyColor,&theNewColor))
  203.         gKeyColor = theNewColor;
  204.     return;
  205. }
  206.  
  207.  
  208. /* The SetPlayAllFrames() function is called by the "Play
  209.    every frame" menu item, in the "Movie Options" Menu.
  210.    This calls a movie controller action to */ 
  211.  
  212. #pragma segment Test
  213. Boolean    SetPlayAllFrames(Boolean playAllFrames)
  214. {
  215.     MovieDocHndl    theDocH;
  216.     WindowPtr        theWindow;
  217.     ComponentResult    theResult;
  218.     
  219.     playAllFrames = !playAllFrames;
  220.     if (gMovieOpen)
  221.     {
  222.         theWindow = FrontWindow();
  223.         theDocH = (MovieDocHndl)GetWRefCon(theWindow);
  224.         if (playAllFrames)
  225.             theResult = MCDoAction((**theDocH).theController,mcActionSetPlayEveryFrame,(Ptr)true);
  226.         else
  227.             theResult = MCDoAction((**theDocH).theController,mcActionSetPlayEveryFrame,(Ptr)false);
  228.         if (theResult != noErr)
  229.             DisplayAlert (rGenAlert,rErrMessages,1);
  230.     }
  231.     return playAllFrames;
  232. }
  233.  
  234.  
  235. #pragma segment Test
  236. Boolean    SetLoopMovie(Boolean loopMovie)
  237. {
  238.     MovieDocHndl    theDocH;
  239.     WindowPtr        theWindow;
  240.     ComponentResult    theResult;
  241.     
  242.     loopMovie = !loopMovie;
  243.     if (gMovieOpen)
  244.     {
  245.         theWindow = FrontWindow();
  246.         theDocH=(MovieDocHndl)GetWRefCon(theWindow);
  247.         if (loopMovie)
  248.             theResult = MCDoAction((**theDocH).theController,mcActionSetLooping,(Ptr)true);
  249.         else
  250.             theResult = MCDoAction((**theDocH).theController,mcActionSetLooping,(Ptr)false);
  251.         if (theResult !=noErr)
  252.             DisplayAlert (rGenAlert,rErrMessages,1);
  253.     }
  254.     return loopMovie;
  255. }
  256.  
  257.  
  258. #pragma segment Test
  259. void TransparentKeyMode(WindowPtr theWindow)
  260. {
  261.     MovieDocHndl    theDocHndl;
  262.     CGrafPtr        oldPort;
  263.     GDHandle        oldDevice;
  264.     Rect            theRect;
  265.  
  266.     theRect = (*gOffscreenPort).portRect;
  267.     theDocHndl = (MovieDocHndl)GetWRefCon(theWindow);
  268.     GetGWorld(&oldPort,&oldDevice);
  269.     // use CopyBits()to perform croma keying
  270.     SetGWorld(gBackGroundPort,nil);
  271.     RGBForeColor(&kRGBBlack);
  272.     RGBBackColor(&kRGBWhite);
  273.     CopyBits((BitMap*)(*gBackGndPictPM),
  274.         (BitMap*)(*gBackGndPixmap),
  275.         &(*gBackGroundPicture).portRect,&theRect,srcCopy,nil);
  276.     if (gMovieBackGrnd)
  277.     {
  278.         SetGWorld(gOffscreenPort,nil);
  279.         RGBForeColor(&kRGBBlack);
  280.         RGBBackColor(&gKeyColor);
  281.         CopyBits((BitMap*)(*gBackGndPixmap),
  282.             (BitMap*)(*gMoviePixmap),
  283.             &theRect,&theRect,transparent,nil);
  284.         SetGWorld((CWindowPtr)theWindow,oldDevice);
  285.         RGBForeColor(&kRGBBlack);
  286.         RGBBackColor(&kRGBWhite);
  287.         CopyBits((BitMap*)(*gMoviePixmap),
  288.             (BitMap*)&((*theWindow).portBits),
  289.             &theRect,&theRect,srcCopy,nil);
  290.     }
  291.     else
  292.     {
  293.         SetGWorld(gBackGroundPort,nil);
  294.         RGBForeColor(&kRGBBlack);
  295.         RGBBackColor(&gKeyColor);
  296.         CopyBits((BitMap*)(*gMoviePixmap),
  297.             (BitMap*)(*gBackGndPixmap),
  298.             &theRect,&theRect,transparent,nil);
  299.         SetGWorld((CWindowPtr)theWindow,oldDevice);
  300.         RGBForeColor(&kRGBBlack);
  301.         RGBBackColor(&kRGBWhite);
  302.         CopyBits((BitMap*)(*gBackGndPixmap),
  303.             (BitMap*)&((*theWindow).portBits),
  304.             &theRect,&theRect,srcCopy,nil);
  305.     }
  306.     return;
  307. }
  308.  
  309.  
  310. #pragma segment Test
  311. void ModifierTrackMode(WindowPtr theWindow)
  312. {
  313.     MovieDocHndl                        theDocHndl;
  314.     ModifierTrackGraphicsModeRecord        theModifierStruct;
  315.     long                                theTrackIndex,
  316.                                         theTrackCount;
  317.     Track                                theTrack,
  318.                                         theModifierTrack;
  319.     Media                                theMedia;
  320.     QTAtomContainer                        inputMap;
  321.     QTAtom                                inputAtom;
  322.     OSType                                theMediaType,
  323.                                         inputType;
  324.     short                                resRefNum,
  325.                                         count;
  326.     
  327.     if (gMovieOpen)
  328.     {
  329.         theDocHndl = (MovieDocHndl)GetWRefCon(theWindow);
  330.         SetMovieGWorld((**theDocHndl).theMovie,(CGrafPtr)theWindow,nil);
  331.         theTrackCount = GetMovieTrackCount((**theDocHndl).theMovie);
  332.         theModifierStruct.graphicsMode = transparent;
  333.         theModifierStruct.opColor = gKeyColor;
  334.         theModifierTrack = GetMovieIndTrack((**theDocHndl).theMovie,theTrackCount+1);
  335.         // step thru until first video track found
  336.         for (count=1;count <=theTrackCount;count++)
  337.         {
  338.             theTrack = GetMovieIndTrack((**theDocHndl).theMovie,count);
  339.             theMedia = GetTrackMedia(theTrack);
  340.             GetMediaHandlerDescription(theMedia,&theMediaType,nil,nil);
  341.             if (theMediaType == VideoMediaType)
  342.             {
  343.                 AddTrackReference(theTrack,theModifierTrack,
  344.                                   kTrackModifierTypeGraphicsMode,&theTrackIndex);
  345.                 count = theTrackCount;    // bump track count
  346.             }
  347.             // create and add the input map
  348.             GetMediaInputMap(theMedia,&inputMap);
  349.             QTInsertChild( inputMap, kParentAtomIsContainer, kTrackModifierInput, theTrackIndex,
  350.                   0, 0, nil,&inputAtom);
  351.                   
  352.             QTInsertChild( inputMap, inputAtom, kTrackModifierType, 1, 0, 
  353.                    sizeof(kTrackModifierTypeGraphicsMode), &inputType, nil );
  354.                    
  355.             SetMediaInputMap(theMedia, inputMap );
  356.             QTDisposeAtomContainer(inputMap );
  357.     
  358.         }
  359.         // save changes to movie
  360.         OpenMovieFile(&(**theDocHndl).theFileSpec,&resRefNum,fsRdWrPerm);
  361.         UpdateMovieResource((**theDocHndl).theMovie,resRefNum,(**theDocHndl).theMovieResID,nil);
  362.         CloseMovieFile(resRefNum);
  363.     }
  364.     return;
  365. }
  366.  
  367.  
  368. #pragma segment Test
  369. void VideoGraphicsMode(WindowPtr theWindow, Boolean SetVGM)
  370. {
  371.     MovieDocHndl        theDocHndl;
  372.     long                theTrackCount;
  373.     Media                theMedia;
  374.     Track                movieTrack = nil;
  375.     OSType                theMediaType;
  376.     short                count;
  377.     
  378.     if (gMovieOpen)
  379.     {
  380.         theDocHndl = (MovieDocHndl)GetWRefCon(theWindow);
  381.         SetMovieGWorld((**theDocHndl).theMovie,(CGrafPtr)theWindow,nil);
  382.         theTrackCount = GetMovieTrackCount((**theDocHndl).theMovie);
  383.         for (count=1;count <=theTrackCount;count++)
  384.         {
  385.             movieTrack = GetMovieIndTrack((**theDocHndl).theMovie,count);
  386.             theMedia = GetTrackMedia(movieTrack);
  387.             GetMediaHandlerDescription(theMedia,&theMediaType,nil,nil);
  388.             if (theMediaType == VideoMediaType)
  389.             {
  390.                 if (SetVGM)
  391.                 {
  392.                     if (SetVideoMediaGraphicsMode(GetMediaHandler(theMedia),transparent,&gKeyColor))
  393.                         DisplayAlert (rGenAlert,rErrMessages,1);
  394.                 }
  395.                 else if (!SetVGM)
  396.                 {
  397.                     if (SetVideoMediaGraphicsMode(GetMediaHandler(theMedia),srcCopy,&kRGBWhite))
  398.                         DisplayAlert (rGenAlert,rErrMessages,1);
  399.                 }
  400.             }
  401.         }
  402.     }
  403.     return;
  404. }
  405.  
  406.  
  407. #pragma segment Test
  408. OSErr    DestroyModifierTrack(MovieDocHndl theDocH)
  409. {
  410.     long            theTrackCount;
  411.     Track            theTrack,
  412.                     theModifierTrack;
  413.     Media            theMedia;
  414.     OSType            theMediaType;
  415.     OSErr            theError;
  416.     short            resRefNum,
  417.                     count;
  418.     
  419.     theError = OpenMovieFile(&(**theDocH).theFileSpec,&resRefNum,fsRdWrPerm);
  420.     theTrackCount = GetMovieTrackCount((**theDocH).theMovie);
  421.     theModifierTrack = GetMovieIndTrack((**theDocH).theMovie,theTrackCount);
  422.     theError |= GetMoviesError();
  423.     // step thru until first video track found
  424.     for (count=1;count <=theTrackCount;count++)
  425.     {
  426.         theTrack = GetMovieIndTrack((**theDocH).theMovie,count);
  427.         theMedia = GetTrackMedia(theTrack);
  428.         GetMediaHandlerDescription(theMedia,&theMediaType,nil,nil);
  429.         if (theMediaType == VideoMediaType)
  430.         {
  431.             SetMediaInputMap(theMedia,nil);
  432.             count = theTrackCount;    // bump track count
  433.         }
  434.     }
  435.     theError |= UpdateMovieResource((**theDocH).theMovie,resRefNum,
  436.                                     (**theDocH).theMovieResID,nil);
  437.     CloseMovieFile(resRefNum);
  438.     return theError;
  439. }
  440.